import c4d
import os
import sys
import re
import base64

from c4d import gui, plugins, bitmaps, utils, documents

PLUGIN_ID = 1037230
SCRIPT_INFO = 1001
ANALYZE = 1002
SCRIPT_NAME = 1003

def Decode(string):
    return base64.b64decode(string)

def Encode(string):
    return base64.b64encode(string.encode("utf-8"))

def ClearUserData(tag):
    for id, bc in tag.GetUserDataContainer():
        del(tag[id])
        tag.RemoveUserData(id)
        
    tracks = tag.GetCTracks()
    
    for item in tracks:
        curve = item.GetCurve()
        curve.FlushKeys()
        item.Remove()

    c4d.EventAdd()

def AddUserData(obj, type, unit, name, value):
    if obj is None: return

    bc = c4d.GetCustomDataTypeDefault(type)
    bc[c4d.DESC_NAME] = name
    bc[c4d.DESC_UNIT] = unit

    element = obj.AddUserData(bc)
    if type == c4d.DTYPE_COLOR:
        colorStrCollection = value.split("_")
        r = float(colorStrCollection[0])
        g = float(colorStrCollection[1])
        b = float(colorStrCollection[2])
        color = c4d.Vector(r,g,b)
        obj[element] = color
    elif type == c4d.DTYPE_VECTOR:
        vectorStrCollection = value.split("_")
        x = float(vectorStrCollection[0])
        y = float(vectorStrCollection[1])
        z = float(vectorStrCollection[2])
        vec = c4d.Vector(x,y,z)
        obj[element] = vec
    else:
        obj[element] = value
        
    c4d.EventAdd()

def AnalyzeFieldInfo(sourceString):
    result = list()
    fields = sourceString.split(",")
    
    for item in fields:
        fieldInfo = item.split("#")

        if len(fieldInfo) < 3:
            break
        
        name = fieldInfo[0].split("-")[1]
        type = fieldInfo[1].split("-")[1]
        value = fieldInfo[2].split("-")[1]
        
        result.append((name,type,Decode(value)))

    return result

class Entry(plugins.TagData):

    def Init(self, node):
    
        return True

    def Message(self, node, type, data):
    
        if type==c4d.MSG_DESCRIPTION_COMMAND:
        
            bt = data['id'][0].id 
            doc = c4d.documents.GetActiveDocument()
        
            if bt == ANALYZE:
                str = node[SCRIPT_INFO]
                splitInfo = str.split("*")
                
                if len(splitInfo) < 2:return True
                
                node[SCRIPT_NAME] = splitInfo[0]
                
                listInfo = AnalyzeFieldInfo(splitInfo[1])
                
                ClearUserData(node)
                
                for item in listInfo:
                    name,type,value = item

                    if type == "bool":
                        AddUserData(node, c4d.DTYPE_BOOL, c4d.DESC_UNIT_INT, name, bool(value))
        
                    if type == "float":
                        AddUserData(node, c4d.DTYPE_REAL, c4d.DESC_UNIT_FLOAT, name, float(value))
        
                    if type == "int":
                        AddUserData(node, c4d.DTYPE_LONG, c4d.DESC_UNIT_INT, name, int(value))
        
                    if type == "vector":
                        AddUserData(node, c4d.DTYPE_VECTOR, c4d.DESC_UNIT_FLOAT, name, value)
        
                    if type == "color":
                        AddUserData(node, c4d.DTYPE_COLOR, c4d.DESC_UNIT_FLOAT, name, value)
        
                    if type == "string":
                        AddUserData(node, c4d.DTYPE_STRING, None, name, value)
        
                node[SCRIPT_INFO] = ""
                
        return True
        
if __name__ == "__main__":
    bmp = bitmaps.BaseBitmap()
    dir, file = os.path.split(__file__)
    fn = os.path.join(dir, "res", "tag.png")
    bmp.InitWith(fn)
    
    plugins.RegisterTagPlugin(id = PLUGIN_ID, str="Unity Script Tag",
                              info = c4d.TAG_MULTIPLE|c4d.TAG_VISIBLE, g=Entry,
                              description = "unityscripttag", icon=bmp)